# -*- coding: utf-8 -*-
#
# Copyright (C) 2017 Google
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
<%= lines(autogen_notice :python) -%>

from __future__ import (absolute_import, division, print_function)
__metaclass__ = type

DOCUMENTATION = """
lookup: gcp_lookup
author:
  - Google (@googlecloudplatform)
version_added: "2.6"
requirements:
  - python >= 2.6
  - requests >= 2.18.4
  - google-auth >= 1.3.0
extends_documentation_fragment:
  - gcp
short_description: Look up and verify GCP Attributes
description:
  - Describes attributes on GCP. You can specify one of the listed
    attribute choices or omit it to see all attributes.
options:
  attribute:
    description: The attribute for which to get the value(s).
    default: null
    choices:
<%
  # Looking for virtual objects that export for ResourceRefs
  virtuals = products.map { |product, _| product.objects }
                     .flatten
                     .select(&:virtual)
                     .reject { |obj| obj.exports.nil? }
-%>
<% virtuals.each do |virt| -%>
      - <%= Google::StringUtils.underscore(virt.name) %>
<% end -%>
  return:
    description: An optional value to describe what part of the attribute should
                 be returned
    default: null
"""

EXAMPLES = """
vars:
  account_details: "{{ lookup('gcp_lookup',
                              attribute='region',
                              label='us-west1',
                              auth_kind='serviceaccount',
                              service_account_file='/tmp/my_account.json',
                              project='test-project',
                              scopes=['https://www.googleapis.com/auth/compute']) }}"
  # us-west1
  account_details: "{{ lookup('gcp_lookup',
                              attribute='region',
                              return='self_link',
                              label='us-west1',
                              auth_kind='serviceaccount',
                              service_account_file='/tmp/my_account.json',
                              project='test-project',
                              scopes=['https://www.googleapis.com/auth/compute']) }}"
  # us-west1

"""

RETURN = """
"""


################################################################################
# Imports
################################################################################

from ansible.errors import AnsibleError
from ansible.plugins import AnsiblePlugin
from ansible.plugins.lookup import LookupBase
from ansible.module_utils.gcp_utils import navigate_hash, GcpSession, GcpRequestException
import json

################################################################################
# Main
################################################################################


class GcpModule(object):
    def __init__(self, options):
        self.params = options
        if 'label' in self.params:
            self.params['name'] = self.params['label']
            del self.params['label']

    def fail_json(self, **kwargs):
        raise AnsibleError(kwargs['msg'])


<% virtuals.each do |object| -%>
<%
    prod_name = object.__product.prefix[1..-1]
-%>
class Gcp<%= object.name -%>(object):
    def __init__(self, options):
        self.module = GcpModule(options)

        self.kind = <%= quote_string(object.kind) %>
        self.link = <%= self_link_url(object) %>.format(**self.module.params)

    def _fetch_resource(self):
        auth = GcpSession(self.module, <%= quote_string(prod_name) -%>)
        return self._return_if_object(auth.get(self.link))

    def _return_if_object(self, response):
        # If not found, return nothing.
        if response.status_code == 404:
            return None

        # If no content, return nothing.
        if response.status_code == 204:
            return None

        try:
            response.raise_for_status
            result = response.json()
        except getattr(json.decoder, 'JSONDecodeError', ValueError) as inst:
            self.module.fail_json(msg="Invalid JSON response with error: %s" % inst)
        except GcpRequestException as inst:
            self.module.fail_json(msg="Network error: %s" % inst)

        if navigate_hash(result, ['error', 'errors']):
            self.module.fail_json(msg=navigate_hash(result, ['error', 'errors']))
        if result['kind'] != self.kind:
            self.module.fail_json(msg="Incorrect result: {kind}".format(**result))

        return result

    def run(self):
        response = self._fetch_resource()
<%
    default = get_code_multiline config, 'default'
    if default.nil?
      if object.exports[0].is_a? String
        default = object.exports[0]
      else
        default = Google::StringUtils.underscore(object.exports[0].name)
      end
    end
-%>
        if 'return' in self.module.params:
            return response[self.module.params['return']]
        return response[<%= quote_string(default) -%>]


<% end # virtuals.each -%>
class LookupModule(LookupBase):
    def run(self, terms, variables, **kwargs):

        self.set_options(var_options=variables, direct=kwargs)
<%
  opts_code = []
  virtuals.each do |object|
    name = Google::StringUtils.underscore(object.name)
    opts_code << "#{quote_string(name)}: Gcp#{object.name}"
  end
-%>
        options = {
<%= lines(indent_list(opts_code, 12)) -%>
        }

        return str(options[kwargs['attribute']](kwargs).run())
